package com.jh.paymentchannel.service;

//import static org.hamcrest.CoreMatchers.nullValue;

import cn.jh.common.tools.Log;
import cn.jh.common.utils.CommonConstants;
import com.jh.paymentchannel.business.TopupPayChannelBusiness;
import com.jh.paymentchannel.pojo.SDJCallbackDto;
import com.jh.paymentchannel.pojo.SDJRegister;
import com.jh.paymentchannel.util.Util;
import com.jh.paymentchannel.util.sdj.Coder;
import com.jh.paymentchannel.util.sdj.SignatureTools;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

// 停止服务
public class SDJCallBackService {

	private static final Logger log = LoggerFactory.getLogger(SDJCallBackService.class);

	@Autowired
	Util util;

	@Autowired
	private TopupPayChannelBusiness topupPayChannelBusiness;

	// 证书地址
//	@Value("${sdj.cerpath}")
	private String CER_PATH;
	// 证书地址
//	@Value("${sdj.jkspath}")
	private String JKS_PATH;
	// 密码
//	@Value("${sdj.password}")
	private String PASSWORD;


	@RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/topup/sdj/notify_call")
	public void quickPayCallback(HttpServletRequest request, HttpServletResponse response
			
	) throws Exception {

		InputStream inputStream = request.getInputStream();
		ByteArrayOutputStream byteArray = null;
		byteArray = new ByteArrayOutputStream();
		byte[] dat = new byte[2048];
		int l = 0;
		while ((l = inputStream.read(dat, 0, 2048)) != -1) {
			byteArray.write(dat, 0, l);
		}
		byteArray.flush();
		log.info("ByteArrayOutputStream2String=============" + new String(byteArray.toByteArray(), "UTF-8"));
		String info = new String(byteArray.toByteArray(), "UTF-8");
		JSONObject jsonInfo = JSONObject.fromObject(info);
		log.info("jsonInfo=============" + jsonInfo.toString());
		inputStream.close();
		byteArray.close();
		String resString = "fail";
		String execMsg = jsonInfo.getString("execMsg");
		String execCode = jsonInfo.getString("execCode");
		String data = jsonInfo.getString("data");
		String isSuccess = jsonInfo.getString("isSuccess");
		jsonInfo = JSONObject.fromObject(data);
		log.info("msg=============" + data);

		SDJCallbackDto sdjCallbackDto = new SDJCallbackDto();
		sdjCallbackDto.setData(data);
		sdjCallbackDto.setExecCode(execCode);
		sdjCallbackDto.setExecMsg(execMsg);
		sdjCallbackDto.setIsSuccess("true".equals(isSuccess));
		log.info("【快捷支付-系统回调】参数对象:{}", execCode, execMsg, isSuccess, data);
		log.info("【快捷支付-系统回调】参数对象:{}", sdjCallbackDto);
		if (checkSignature(sdjCallbackDto)) {
			// 验签通过之后，实现自己的业务逻辑
		//	log.info("【快捷支付-系统回调】验签成功............");
			
			PrintWriter write = response.getWriter();
			write.print("{'code':'000000','message':'success'}");
			write.flush();
			
			String datas = sdjCallbackDto.getData();
			JSONObject obj = JSONObject.fromObject(datas);
			String orderNo = obj.getString("orderNo");

			String retMsgJson = "";
			try {
				Log.setLogFlag(true);
				Log.println("---交易： 订单结果异步通知-------------------------");

				log.info("交易： 订单结果异步通知===================");
				if ("000000".equals(sdjCallbackDto.getExecCode())) { // 订单已支付;

					// 1、检查Amount和商户系统的订单金额是否一致
					// 2、订单支付成功的业务逻辑处理请在本处增加（订单通知可能存在多次通知的情况，需要做多次通知的兼容处理）；
					// 3、返回响应内容

					synchronized (this) {
						// **更新订单状态*//*
						// **调用下单，需要得到用户的订单信息*//*
						RestTemplate restTemplate = new RestTemplate();

						URI uri = util.getServiceUrl("transactionclear", "error url request!");
						String url = uri.toString() + "/v1.0/transactionclear/payment/update";

						// **根据的用户手机号码查询用户的基本信息*//*
						MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<String, String>();
						requestEntity.add("status", "1");
						requestEntity.add("order_code", orderNo);
						String result = restTemplate.postForObject(url, requestEntity, String.class);

						log.info("订单状态修改成功===================");

						// **判断是否有外放的通道的处理， 如果有那么继续回调外放哦*//*
						uri = util.getServiceUrl("transactionclear", "error url request!");
						url = uri.toString() + "/v1.0/transactionclear/payment/query/ordercode";

						requestEntity = new LinkedMultiValueMap<String, String>();
						requestEntity.add("order_code", orderNo);
						result = restTemplate.postForObject(url, requestEntity, String.class);

						JSONObject jsonObject = JSONObject.fromObject(result);
						JSONObject resultObj = jsonObject.getJSONObject("result");
						String outMerOrdercode = resultObj.getString("outMerOrdercode");
						String orderdesc = resultObj.getString("desc");
						String phone = resultObj.getString("phone");
						String tranamount = resultObj.getString("amount");
						String channelTag = resultObj.getString("channelTag");
						String notifyURL = resultObj.getString("outNotifyUrl");
						if (outMerOrdercode != null && !outMerOrdercode.equalsIgnoreCase("")) {
							uri = util.getServiceUrl("channel", "error url request!");
							url = uri.toString() + "/v1.0/channel/callback/yilian/notify_call";
							requestEntity = new LinkedMultiValueMap<String, String>();
							requestEntity.add("merchant_no", phone);
							requestEntity.add("amount", tranamount);
							requestEntity.add("channel_tag", channelTag);
							requestEntity.add("order_desc", URLEncoder.encode(orderdesc, "UTF-8"));
							requestEntity.add("order_code", outMerOrdercode);
							requestEntity.add("sys_order", orderNo);
							requestEntity.add("notify_url", URLEncoder.encode(notifyURL, "UTF-8"));
							result = restTemplate.postForObject(url, requestEntity, String.class);
						}

						log.info("订单已支付!");
					}
				} else {
					// 1、订单支付失败的业务逻辑处理请在本处增加（订单通知可能存在多次通知的情况，需要做多次通知的兼容处理，避免成功后又修改为失败）；
					// 2、返回响应内容

					log.info("订单支付失败!失败信息=" + sdjCallbackDto.getExecMsg());
				}
			} catch (Exception e) {
				log.error(e.getMessage());
			}
			log.info("-----处理完成----");

			
		}else {
			log.info("验签失败");
			PrintWriter write = response.getWriter();
			write.print("{'code':'000001','message':'错误信息'}");
			write.flush();
		}
	}

	private boolean checkSignature(SDJCallbackDto dto) {
		try {
			String data = dto.getData();
			JSONObject obj = JSONObject.fromObject(data);
			String sign = obj.getString("sign");
			String signature = obj.getString("signature");
			String orderNo = obj.getString("orderNo");
			RestTemplate restTemplate = new RestTemplate();
			URI uri = util.getServiceUrl("transactionclear", "error url request!");
			String url = uri.toString() + "/v1.0/transactionclear/payment/query/ordercode";
			MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<String, String>();
			requestEntity.add("order_code", orderNo);
			String result = restTemplate.postForObject(url, requestEntity, String.class);
			log.info("RESULT================" + result);
			JSONObject jsonObject = JSONObject.fromObject(result);
			JSONObject resultObj = jsonObject.getJSONObject("result");
			
			String userId = resultObj.getString("userid");
			SDJRegister sdjRegister = topupPayChannelBusiness.getSDJRegister(Long.parseLong(userId));
			String merKey = sdjRegister.getMerKey();
			if (SignatureTools.verifySign(signature, sign, CER_PATH)) {
				StringBuffer sb = new StringBuffer();
				sb.append("orderNo=" + obj.getString("orderNo"));
				sb.append("&");
				sb.append("payAmount=" + obj.getString("payAmount"));
				sb.append("&");
				sb.append("payeeId=" + obj.getString("payeeId"));
				sb.append("&");
				sb.append("tradeNo=" + obj.getString("tradeNo"));
				sb.append("&");
				sb.append("tradeStatus=" + obj.getString("tradeStatus"));
				sb.append("&");
				// 改成当前商户对应的merKey
				sb.append("merKey=" + merKey);
				String jksCertificatePath = JKS_PATH;
			//	log.info("jksCertificatePath======="+jksCertificatePath);
				String password = PASSWORD;
			//	log.info("password======="+password);

				log.info("sb======"+sb);
				/** sha256加密 **/
				String sha256Sign = Coder.encryptSHA256(sb.toString());
				/** 证书加密数据 **/
				String decryptSgnature = SignatureTools.decrypt(signature, jksCertificatePath, password);
				/**证书签名数据**/  
				log.info("sha256Sign======="+sha256Sign);
				log.info("decryptSgnature======="+decryptSgnature);
				
				if (decryptSgnature.equals(sha256Sign)) {
					log.info("验签通过");
					return true;
				}
			}
		} catch (Exception e) {
			log.error("验签异常:{}", e);
		}
		return false;
	}

	@RequestMapping(method = RequestMethod.GET, value = "/v1.0/paymentchannel/topup/sdj/ret_url")
	public String sdjretcall(HttpServletRequest request, HttpServletResponse response) throws IOException {
		log.info("进入接口/v1.0/paymentchannel/topup/kj/ret_url=============== " + request.getParameterMap().toString());
		Map<String, String[]> data = request.getParameterMap();
		String merchantNo = request.getParameter("merchantNo");
		if (!"".equals(merchantNo) && null != merchantNo) {
			if (data.containsKey("errMsg")) {

				String errMsg = request.getParameter("errMsg");
				log.info("errMsg====" + errMsg);
				if (null == errMsg || "".equals(errMsg)) {

					return "redirect:http://1.xinli2017.applinzi.com/login/zhufucg.html";
				} else {
					return "redirect:http://1.xinli2017.applinzi.com/login/zhufusb.html";
				}
			} else {
				return "redirect:http://1.xinli2017.applinzi.com/login/zhufucg.html";
			}
		}

		return "redirect:http://1.xinli2017.applinzi.com/login/zhufucg.html";
	}

	@RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/topup/sdj/querysdjid")
	public @ResponseBody Object findSDJRegisterUserId(HttpServletRequest request,
			@RequestParam(value = "user_id") long userid) {

		SDJRegister sdjRegister = topupPayChannelBusiness.getSDJRegister(userid);
		Map map = new HashMap();

		if (sdjRegister == null) {
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESULT, sdjRegister);
			map.put(CommonConstants.RESP_MESSAGE, "失败");
			return map;

		} else {
			map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
			map.put(CommonConstants.RESULT, sdjRegister);
			map.put(CommonConstants.RESP_MESSAGE, "成功");
			return map;
		}

	}

}
